package com.bmps.springcloud.insuredmicroservice.controller.accept;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.bmps.springcloud.common.response.TaskResponseModel;
import com.bmps.springcloud.common.task.TaskExecutor;
import com.bmps.springcloud.common.task.bean.RequestObject;
import com.bmps.springcloud.insuredmicroservice.callback.accept.*;
import com.bmps.springcloud.insuredmicroservice.callback.accept.thirdparty.PhoneVerifyUnderWritingCallBack;
import com.bmps.springcloud.insuredmicroservice.callback.accept.thirdparty.TransitUnderwritingCallBack;
import com.bmps.springcloud.insuredmicroservice.config.accept.ProductConfig;
import com.bmps.springcloud.insuredmicroservice.constant.accept.AcceptConstant;
import com.bmps.springcloud.insuredmicroservice.constant.accept.StrategyConstant;
import com.bmps.springcloud.insuredmicroservice.constant.accept.ThirdPartyConstant;
import com.bmps.springcloud.insuredmicroservice.constant.accept.UnderWriteConstant;
import com.bmps.springcloud.insuredmicroservice.model.accept.DeclinatureRuleModel;
import com.bmps.springcloud.insuredmicroservice.model.accept.ResponseListModel;
import com.bmps.springcloud.insuredmicroservice.model.accept.response.AcceptResponseDataModel;
import com.bmps.springcloud.insuredmicroservice.model.accept.response.ResponseProductInfoModel;
import com.bmps.springcloud.insuredmicroservice.model.accept.response.ResultModel;
import com.bmps.springcloud.insuredmicroservice.model.accept.resquest.*;
import com.bmps.springcloud.insuredmicroservice.model.thirdparty.TaskResponseExtensionModel;
import com.bmps.springcloud.insuredmicroservice.model.thirdparty.bairong.BaiRongResponseModel;
import com.bmps.springcloud.insuredmicroservice.model.thirdparty.cbit.CbitResponseModel;
import com.bmps.springcloud.insuredmicroservice.model.thirdparty.transit.CloudResponseModel;
import com.bmps.springcloud.insuredmicroservice.model.thirdparty.transit.ConclusionModel;
import com.bmps.springcloud.insuredmicroservice.model.thirdparty.transit.SunResponseModel;
import com.bmps.springcloud.insuredmicroservice.model.thirdparty.transit.UnderwriteRequestModel;
import com.bmps.springcloud.insuredmicroservice.service.RedisService;
import com.bmps.springcloud.insuredmicroservice.service.accept.HistoryVerificationService;
import com.bmps.springcloud.insuredmicroservice.service.accept.InsuranceAcceptService;
import com.bmps.springcloud.insuredmicroservice.service.underwrite.AcceptService;
import com.bmps.springcloud.insuredmicroservice.service.underwrite.strategy.conclusion.ConclusionStrategy;
import com.bmps.springcloud.insuredmicroservice.service.underwrite.strategy.conclusion.ConclusionStrategyFactory;
import com.bmps.springcloud.insuredmicroservice.service.underwrite.thirdparty.ThirdPartyTransferService;
import com.bmps.springcloud.insuredmicroservice.service.underwrite.thirdparty.ThirdPartyUnderwritingService;
import com.bmps.springcloud.insuredmicroservice.util.accept.AcceptUtil;
import com.bmps.springcloud.insuredmicroservice.util.trial.TrialUtil;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.Callable;
import java.util.stream.Collectors;

/**
 * @author lyw
 * @date 2019-09-24 20:36:44
 */
@Component
public class ExecuteConcurrentBatchTask {

    private static Logger logger = LoggerFactory.getLogger(ExecuteConcurrentBatchTask.class);

    private final TaskExecutor taskExecutor;

    private final AcceptService acceptService;

    private final ProductConfig productConfig;

    private final RedisService redisService;

    private final InsuranceAcceptService insuranceAcceptService;

    private final HistoryVerificationService historyVerificationService;

    private final ThirdPartyTransferService thirdPartyTransferService;

    private final ThirdPartyUnderwritingService thirdPartyUnderwritingService;


    public ExecuteConcurrentBatchTask(TaskExecutor taskExecutor, AcceptService acceptService,
                                      ProductConfig productConfig, RedisService redisService,
                                      HistoryVerificationService historyVerificationService, InsuranceAcceptService insuranceAcceptService, ThirdPartyTransferService thirdPartyTransferService, ThirdPartyUnderwritingService thirdPartyUnderwritingService) {
        this.taskExecutor = taskExecutor;
        this.acceptService = acceptService;
        this.productConfig = productConfig;
        this.insuranceAcceptService = insuranceAcceptService;
        this.historyVerificationService = historyVerificationService;
        this.redisService = redisService;
        this.thirdPartyTransferService = thirdPartyTransferService;
        this.thirdPartyUnderwritingService = thirdPartyUnderwritingService;
    }


    public AcceptResponseDataModel executeConcurrentTask(AcceptRequestDataModel acceptRequestDataModel) {
        List<Callable<TaskResponseModel>> baseTaskCallbackList = new ArrayList<>();
        RequestObject requestObject;
        //相似客户和续期账号校验
        List<Object> parameters = new ArrayList<>(16);
        parameters.add(acceptRequestDataModel.getRequest());
        //Callable<TaskResponseModel> conflictInfoCallBack = new CheckConflictCallBack(AcceptConstant.TASK_CONFLICTING_INFO, parameters, this.acceptService);
        //baseTaskCallbackList.add(conflictInfoCallBack);
        //电话校验
        // if (AcceptUtil.isCheckAppntMobilePhone(acceptRequestDataModel.getRequest())) {
        //     PhoneVerifyRequestModel requestModel = thirdPartyTransferService.getPhoneVerifyRequestModel(acceptRequestDataModel.getRequest());
        //     requestObject = new RequestObject();
        //     requestObject.setParams(requestModel);
        //     requestObject.setAccept(acceptRequestDataModel.getRequest().getCustInfo());

        //     Callable<TaskResponseModel> phoneVerifyCallBack = new PhoneVerifyUnderWritingCallBack(AcceptConstant.TASK_PHONE_VERIFY, requestObject, thirdPartyUnderwritingService);
        //     baseTaskCallbackList.add(phoneVerifyCallBack);
        // }

        //第三方核保任务
        // Set<UnderwriteRequestModel> underwriteRequestSet = thirdPartyTransferService.getRequestModels(acceptRequestDataModel.getRequest());
        // if (CollectionUtils.isNotEmpty(underwriteRequestSet)) {
        //     requestObject = new RequestObject();
        //     requestObject.setParams(underwriteRequestSet);
        //     Callable<TaskResponseModel> transitCallBack = new TransitUnderwritingCallBack(AcceptConstant.TASK_TRANSIT_UNDERWRITING, requestObject, thirdPartyUnderwritingService);
        //     baseTaskCallbackList.add(transitCallBack);
        // }
        requestObject = new RequestObject();
        requestObject.setParams(acceptRequestDataModel.getRequest());
        //核保在途保单校验任务
        // Callable<TaskResponseModel> historyVerificationCallBack = new HistoryVerificationCallBack(AcceptConstant.TASK_IDENTITY_VERIFICATION, requestObject,
        //         this.historyVerificationService);
        // baseTaskCallbackList.add(historyVerificationCallBack);
        List<ProductModel> productModelList = acceptRequestDataModel.getRequest().getProductInfo().getProducts().getProduct();
        //保费试算 投核保任务添加   累计风险保额任务添加
        for (ProductModel productModel : productModelList) {
            String riskCode = productModel.getProdCode();
            requestObject = new RequestObject();
            requestObject.setParams(productModel);
            requestObject.setAccept(acceptRequestDataModel);
            //投核保
            Callable<TaskResponseModel> insuredCallBack = new InsuredCallBack(AcceptConstant.TASK_IDENTITY_INSURED + riskCode, this.acceptService,
                    requestObject);
            baseTaskCallbackList.add(insuredCallBack);
            //累计风险保额和累积住院险保额
            List<String> riskStrategys = productConfig.getAccumulatedRiskList();
            // 保费计算保额险种列表
            // add by jacob  2020-06-07 15:00；00
            List<String> amntRisks = productConfig.getAmntList();
            if (AcceptUtil.isStrategy(StrategyConstant.CRITICAL_ILLNESS_INSURANCE, riskCode, riskStrategys)) {
                Callable<TaskResponseModel> callBack = new RiskInsuranceCallBack(AcceptConstant.TASK_IDENTITY_ACCUMULATED + riskCode, this.acceptService,
                        requestObject);
                baseTaskCallbackList.add(callBack);
            }
            if (AcceptUtil.isStrategy(StrategyConstant.INPATIENT_MEDICAL_INSURANCE, riskCode, riskStrategys)) {
                Callable<TaskResponseModel> callBack = new HospitalInsuranceCallBack(AcceptConstant.TASK_IDENTITY_HOSPITAL + riskCode, this.acceptService,
                        requestObject);
                baseTaskCallbackList.add(callBack);
            }
            if (AcceptUtil.isStrategy(StrategyConstant.TRAFFIC_ACCIDENT_INSURANCE, riskCode, riskStrategys)) {
                Callable<TaskResponseModel> callBack = new TrafficInsuranceCallBack(AcceptConstant.TASK_IDENTITY_TRAFFIC + riskCode, this.acceptService,
                        requestObject);
                baseTaskCallbackList.add(callBack);
            }
            if (AcceptUtil.isStrategy(StrategyConstant.DEATH_LIABILITY_INSURANCE, riskCode, riskStrategys)) {
                Callable<TaskResponseModel> callBack = new MinorDeathLiabilityCallBack(AcceptConstant.TASK_IDENTITY_MINOR_DEATH + riskCode, this.acceptService,
                        requestObject);
                baseTaskCallbackList.add(callBack);
            }
            if (AcceptUtil.isStrategy(StrategyConstant.ACCIDENT_INSURANCE, riskCode, riskStrategys)) {
                Callable<TaskResponseModel> callBack = new AccidentInsuranceCallBack(AcceptConstant.TASK_ACCIDENT + riskCode, this.acceptService,
                        requestObject);
                baseTaskCallbackList.add(callBack);
            }

            //试算
            Callable<TaskResponseModel> premiumsCallBack = new PremiumsCallBack(AcceptConstant.TASK_IDENTITY_CALCULATION + riskCode, this.acceptService,
                    requestObject);
            baseTaskCallbackList.add(premiumsCallBack);

            // 计算保额
            if (AcceptUtil.isAmntRisk(productModel.getProdCode(), amntRisks)) {
                Callable<TaskResponseModel> amntCallback = new AmntCallBack(AcceptConstant.TASK_IDENTITY_AMNT + riskCode, this.acceptService,
                        requestObject);
                baseTaskCallbackList.add(amntCallback);
            }

            //特殊险种校验
            if (productConfig.getSpecialRiskList().contains(riskCode)) {
                Callable<TaskResponseModel> generalRiskInsurance = new GeneralRiskInsuranceCallBack(AcceptConstant.TASK_RISK + riskCode, productModel, acceptRequestDataModel.getRequest());
                baseTaskCallbackList.add(generalRiskInsurance);
            }
            //计算加费
            if (productModel.getAddPremEM() > 0) {
                Callable<TaskResponseModel> addPrem = new AddPremCallBack(AcceptConstant.TASK_ADD_PREM + riskCode, productModel, acceptRequestDataModel.getRequest(), acceptService);
                baseTaskCallbackList.add(addPrem);
            }
        }

        List<TaskResponseModel> taskResponseModelList = taskExecutor.execute(baseTaskCallbackList);
        AcceptResponseDataModel acceptResponseDataModel;
        taskResponseModelList.stream().forEach(x -> logger.info(x.toString()));
        for (TaskResponseModel data : taskResponseModelList) {
            if (StringUtils.equals(data.getKey(), AcceptConstant.TASK_ERROR)) {
                acceptResponseDataModel = InsuranceAcceptSupport.bindingExceptionErrors(acceptRequestDataModel.getHeader());
                acceptResponseDataModel.setFlag(false);
                return acceptResponseDataModel;
            } else {
                if (!StringUtils.equals(data.getResultCode(), AcceptConstant.RESULT_SUCCESS_CODE) &&
                        !productConfig.getUnderWriteList().contains(data.getResultCode())) {
                    ResultModel resultModel = new ResultModel(data.getResultCode(), data.getResultMessage());
                    acceptResponseDataModel = AcceptUtil.getResponseResult(acceptRequestDataModel.getHeader(), resultModel, null);
                    acceptResponseDataModel.setFlag(false);
                    return acceptResponseDataModel;
                }

            }
        }
        return dealResult(taskResponseModelList, acceptRequestDataModel, false);
    }


    /**
     * 封装并发任务结果
     *
     * @param taskResponseModelList 任务结果列表
     * @return ResponseListModel
     */
    private ResponseListModel getResponseObjectList(List<TaskResponseModel> taskResponseModelList) {
        ResponseListModel responseListModel = new ResponseListModel();
        taskResponseModelList.forEach(data -> {
            logger.info("【遍历任务】" + data.toString());
            //投核保任务结果
            if (StringUtils.contains(data.getKey(), AcceptConstant.TASK_IDENTITY_INSURED)) {
                responseListModel.addInsured(data);
            }
            //累计风险保额任务结果
            if (StringUtils.contains(data.getKey(), AcceptConstant.TASK_IDENTITY_ACCUMULATED) ||
                    StringUtils.contains(data.getKey(), AcceptConstant.TASK_IDENTITY_HOSPITAL) ||
                    StringUtils.contains(data.getKey(), AcceptConstant.TASK_IDENTITY_TRAFFIC) ||
                    StringUtils.contains(data.getKey(), AcceptConstant.TASK_IDENTITY_MINOR_DEATH) ||
                    StringUtils.contains(data.getKey(), AcceptConstant.TASK_ACCIDENT) ||
                    StringUtils.contains(data.getKey(), AcceptConstant.TASK_RISK)
            ) {
                responseListModel.addAccumulated(data);
            }
            //保费试算任务结果
            if (StringUtils.contains(data.getKey(), AcceptConstant.TASK_IDENTITY_CALCULATION)) {
                responseListModel.addCalculation(data);
            }
            //核保在途保单结果
            if (StringUtils.contains(data.getKey(), AcceptConstant.TASK_IDENTITY_VERIFICATION)) {
                responseListModel.setHistoryVerification(data);
            }
            //第三方核保
            if (StringUtils.contains(data.getKey(), AcceptConstant.TASK_TRANSIT_UNDERWRITING)) {
                responseListModel.setTransit(data);
            }
            // 保额计算结果
            if (StringUtils.contains(data.getKey(), AcceptConstant.TASK_IDENTITY_AMNT)) {
                responseListModel.addAmntList(data);
            }
            //加费计算结果
            if (StringUtils.contains(data.getKey(), AcceptConstant.TASK_ADD_PREM)) {
                responseListModel.addPlusPremList(data);
            }
        });
        return responseListModel;
    }


    /**
     * 分析核保综合结论
     * 优先级保盾云＞中保信＞百融>阳光
     *
     * @param conclusionSet 核保结论集合
     */
    private void analyze(Set<ConclusionModel> conclusionSet,
                         boolean isManual, RequestModel requestModel) {
        CustInfoModel custInfoModel = requestModel.getCustInfo();
        for (ConclusionModel conclusion : conclusionSet) {
            nonGenericConclusion(conclusion, requestModel, isManual);
            if (conclusion.getConclusion() != null) {
                continue;
            }
            int cloudConclusion = conclusion.getCloud() == null ? 2 :
                    this.cloudConclusion(conclusion, isManual, requestModel);
            if (cloudConclusion == 1) {
                conclusion.setConclusion(1);
                conclusion.setMessage(String.format(AcceptConstant.CLOUD_DECLINATURE_MESSAGE, getCustomerName(custInfoModel, conclusion.getId())));
            } else {
                //百融
                BaiRongResponseModel baiRong = conclusion.getBaiRong();
                //0-低 1、2-中 3、4高
                int riskLevel = this.riskLevel(baiRong);
                //中保信
                List<CbitResponseModel> cbitList = conclusion.getCbits();
                boolean cbit = checkCbit(cbitList);
                //阳光
                SunResponseModel sun = conclusion.getSun();
                boolean sunRiskLevel = sunRiskLevel(sun);
                if (isManual) {
                    //人核渠道
                    if (cloudConclusion == 3) {
                        //直接人核
                        conclusion.setConclusion(3);
                        conclusion.setMessage(String.format(AcceptConstant.CLOUD_UNDERWRITING_MESSAGE, getCustomerName(custInfoModel, conclusion.getId())));
                    } else {
                        //中保信存在结论为是 人核
                        if (!cbit) {
                            conclusion.setConclusion(3);
                            conclusion.setMessage(String.format(AcceptConstant.CBIT_UNDERWRITING_MESSAGE, getCustomerName(custInfoModel, conclusion.getId())));
                        } else {
                            //百融风险等级D\E 人核
                            if (riskLevel > 2) {
                                conclusion.setConclusion(3);
                                conclusion.setMessage(String.format(AcceptConstant.BR_UNDERWRITING_MESSAGE, getCustomerName(custInfoModel, conclusion.getId())));
                            } else if (!sunRiskLevel) {
                                conclusion.setConclusion(3);
                                conclusion.setMessage(String.format(AcceptConstant.SUN_UNDERWRITING_MESSAGE, getCustomerName(custInfoModel, conclusion.getId())));
                            } else {
                                //核保通过
                                conclusion.setConclusion(2);
                            }
                        }
                    }

                } else {
                    //低分保盾云
                    if (!cbit) {
                        conclusion.setConclusion(1);
                        conclusion.setMessage(String.format(AcceptConstant.CBIT_DECLINATURE_MESSAGE, getCustomerName(custInfoModel, conclusion.getId())));
                    } else {
                        if (riskLevel > 2) {
                            conclusion.setConclusion(1);
                            conclusion.setMessage(String.format(AcceptConstant.BR_DECLINATURE_MESSAGE, getCustomerName(custInfoModel, conclusion.getId())));
                        } else if (!sunRiskLevel) {
                            conclusion.setConclusion(1);
                            conclusion.setMessage(String.format(AcceptConstant.SUN_DECLINATURE_MESSAGE, getCustomerName(custInfoModel, conclusion.getId())));
                        } else {
                            conclusion.setConclusion(2);
                        }
                    }
                }
            }
        }
    }

    /**
     * 结论判断人核/拒保依据，客户评分标准（目前阳光评分小于400分为高风险、400到500之间为中风险、500分以上为低风险）？
     * 有人核流程：高风险，进入人核；余者正常通过
     * 无人核流程：高风险，拒保；余者正常通过
     *
     * @param sun
     * @return
     */
    private boolean sunRiskLevel(SunResponseModel sun) {
        if (sun != null && StringUtils.equals(ThirdPartyConstant.SUCCESS, sun.getRecode())) {
            try {
                double score = Double.parseDouble(sun.getSunScore());
                if (score < ThirdPartyConstant.SUN_HIGH_RISK) {
                    return false;
                }
            } catch (NumberFormatException e) {
                e.printStackTrace();
                return true;
            }
        }
        return true;
    }

    private void nonGenericConclusion(ConclusionModel conclusion, RequestModel requestModel, boolean isManual) {
        CustInfoModel custInfoModel = requestModel.getCustInfo();
        List<ProductModel> productModels = requestModel.getProductInfo().getProducts().getProduct();
        InsurantModel insurant = getInsurantByIdNo(custInfoModel.getInsurants().getInsurant(), conclusion.getId());
        for (ProductModel productModel : productModels) {
            if (ConclusionStrategyFactory.getKeys().contains(productModel.getProdCode())) {
                boolean isExemption = redisService.exemptionProduct(productModel.getProdCode()) ||
                        redisService.isExemptDuty(productModel.getProdCode(), custInfoModel.getAppnt(),
                                insurant, requestModel.getPolicyInfo().getPolApplyDate());
                boolean flag = insurant != null && productModel.getProdInsSeq() == insurant.getInsSeq() && !isExemption || insurant == null && isExemption;
                if (flag) {
                    ConclusionStrategy conclusionStrategy = ConclusionStrategyFactory.getStrategy(productModel.getProdCode());
                    if (conclusionStrategy != null) {
                        conclusionStrategy.underwrite(conclusion, requestModel, isManual);
                    }
                }
            }
        }
    }

    private InsurantModel getInsurantByIdNo(List<InsurantModel> insurantModelList, String idNo) {
        for (InsurantModel insurantModel : insurantModelList) {
            if (StringUtils.equals(insurantModel.getIdNo(), idNo)) {
                return insurantModel;
            }
        }
        return null;
    }

    private boolean checkCbit(List<CbitResponseModel> cbitList) {
        if (CollectionUtils.isEmpty(cbitList)) {
            return true;
        }
        for (CbitResponseModel cbitResponseModel : cbitList) {
            if (StringUtils.isBlank(cbitResponseModel.getCode()) &&
                    StringUtils.equals(ThirdPartyConstant.CBIT_SUCCESS, cbitResponseModel.getRetCode())) {
                JSONObject data = JSON.parseObject(cbitResponseModel.getData());
                for (String key : data.keySet()) {
                    //延拒概率评分大于等于85分
                    if (StringUtils.equals(ThirdPartyConstant.RISK_SCORE, key)) {
                        if (Double.parseDouble(data.getString(key)) >= 85) {
                            return false;
                        }
                    }
                    //风险存在是
                    if (StringUtils.equals(ThirdPartyConstant.YES, data.getString(key))) {
                        return false;
                    }
                }
            }
        }
        return true;
    }

    private boolean checkApntInform(ProductInfoModel productInfoModel, CustInfoModel custInfoModel) {
        InsurantModel insurantModel;
        AppntModel appntModel = custInfoModel.getAppnt();
        //long age = DateUtil.getYears(appntModel.getAppntBirthday(), new Date());
        for (ProductModel productModel : productInfoModel.getProducts().getProduct()) {
            Object object = redisService.get(AcceptConstant.EXEMPT_DUTY_RISK + productModel.getProdCode());
            insurantModel = AcceptUtil.getInsurantModelBySeq(productModel.getProdInsSeq(), custInfoModel.getInsurants().getInsurant());
            if (object != null &&
                    !AcceptUtil.isSamePerson(insurantModel, appntModel)) {
                // &&age <= (int) object &&  !StringUtils.equals(productInfoModel.getPayIntv(), UnderWriteConstant.SINGLE_PAY)
                if (StringUtils.equals(appntModel.getApntInform(), AcceptConstant.STRING_Y)) {
                    return true;
                }
            }

        }
        return false;
    }


    private int riskLevel(BaiRongResponseModel baiRong) {
        if (baiRong != null && baiRong.getFlag() != null && StringUtils.equals(baiRong.getFlag().getCustrisk(), "1")) {
            String riskLevel = baiRong.getCustrisk().getRisklevel();
            if (StringUtils.equals(riskLevel, ThirdPartyConstant.HIGH_RISK_E)) {
                return 4;
            } else if (StringUtils.equals(riskLevel, ThirdPartyConstant.MEDIUM_HIGH_RISK_D)) {
                return 3;
            } else if (StringUtils.equals(riskLevel, ThirdPartyConstant.MEDIUM_RISK_C)) {
                return 2;
            } else if (StringUtils.equals(riskLevel, ThirdPartyConstant.MEDIUM_LOW_RISK_B)) {
                return 1;
            } else if (StringUtils.equals(riskLevel, ThirdPartyConstant.LOW_RISK_A)) {
                return 0;
            }
        }
        return 0;
    }

    private String getCustomerName(CustInfoModel custInfoModel, String idNo) {
        if (StringUtils.equals(custInfoModel.getAppnt().getIdNo(), idNo)) {
            return custInfoModel.getAppnt().getAppntName();
        }
        for (InsurantModel insurant : custInfoModel.getInsurants().getInsurant()) {
            if (StringUtils.equals(insurant.getIdNo(), idNo)) {
                return insurant.getName();
            }
        }
        return "";
    }

    private int getInSeq(CustInfoModel custInfoModel, String idNo) {
        for (InsurantModel insurant : custInfoModel.getInsurants().getInsurant()) {
            if (StringUtils.equals(insurant.getIdNo(), idNo)) {
                return insurant.getInsSeq();
            }
        }
        return 0;
    }

    private void createMidResultNode(AcceptRequestDataModel acceptRequestDataModel, TaskResponseModel transit) {
        MidResultModel midResultModel = new MidResultModel();
        CustInfoModel custInfoModel = acceptRequestDataModel.getRequest().getCustInfo();
        if (transit != null) {
            Set<ConclusionModel> conclusionModelSet = (Set<ConclusionModel>) ((TaskResponseExtensionModel) transit).getResponse();
            if (CollectionUtils.isNotEmpty(conclusionModelSet)) {
                List<ResultListModel> resultModelList = new ArrayList<>();
                for (ConclusionModel conclusion : conclusionModelSet) {
                    CloudResponseModel cloud = conclusion.getCloud();
                    if (cloud != null) {
                        ResultListModel resultModel = new ResultListModel();
                        resultModel.setInsSeq(String.valueOf(getInSeq(custInfoModel, conclusion.getId())));
                        resultModel.setStatus(String.valueOf(cloud.getStatus()));
                        if (cloud.getStatus() == 900) {
                            resultModel.setStatus(String.valueOf(cloud.getStatus()));
                            resultModel.setInfos("0");
                            resultModel.setErrorMessage(cloud.getData());
                        } else {
                            resultModel.setInfos(String.valueOf(cloud.getInfo()));
                            resultModel.setSerialNo(cloud.getSerialNo());
                            resultModel.setTimeStamp(cloud.getTimestamp());
                        }
                        resultModelList.add(resultModel);
                    }
                }
                midResultModel.setResult(resultModelList);
            }
        }
        acceptRequestDataModel.getRequest().setMidResult(midResultModel);
    }

    private AcceptResponseDataModel dealResult(List<TaskResponseModel> taskResponseModelList, AcceptRequestDataModel acceptRequestDataModel,
                                               boolean isUnderWriting) {
        ResponseListModel responseListModel = getResponseObjectList(taskResponseModelList);
        createMidResultNode(acceptRequestDataModel, responseListModel.getTransit());
        // ResponseProductInfoModel responseProductInfoModel = getPremiumSum(responseListModel.getCalculation());
        ResponseProductInfoModel responseProductInfoModel = getPremiumSum(responseListModel);
        //是否触发非拒保核保规则标识
        // DeclinatureRuleModel declinatureRuleModel = isDeclinatureRule(responseListModel.getInsured());
        DeclinatureRuleModel declinatureRuleModel = isNonDeclinatureRule(taskResponseModelList);
        MidResultModel midResultModel = acceptRequestDataModel.getRequest().getMidResult();
        midResultModel.setMidUWFlag("9");
        List<ProductModel> productModels = acceptRequestDataModel.getRequest().getProductInfo().getProducts().getProduct();
        String agencyCode = acceptRequestDataModel.getRequest().getPolicyInfo().getAgencyCode();
        CustInfoModel custInfoModel = acceptRequestDataModel.getRequest().getCustInfo();
        //人核渠道 且 保单下不存在非核保产品
        boolean isManual = this.manualUnderwriting(productModels, agencyCode);
        StringBuilder message = new StringBuilder();
        boolean flag = true;
        if (isUnderWriting) {
            Set<ConclusionModel> conclusionModelSet = (Set<ConclusionModel>) ((TaskResponseExtensionModel) responseListModel.getTransit()).getResponse();
            if (CollectionUtils.isNotEmpty(conclusionModelSet)) {
                analyze(conclusionModelSet, isManual, acceptRequestDataModel.getRequest());
                for (ConclusionModel conclusionModel : conclusionModelSet) {
                    if (conclusionModel.getConclusion() != null) {
                        //存在拒保
                        if (conclusionModel.getConclusion() == 1) {
                            return createRefuseAcceptResponseDataModel(acceptRequestDataModel.getHeader(), conclusionModel.getMessage());
                            //存在人核
                        } else if (conclusionModel.getConclusion() == 3) {
                            flag = false;
                            message.append(conclusionModel.getMessage());
                            message.append(AcceptConstant.VERTICAL_BAR);
                        }
                    }
                }
            }
        }
        if (flag) {
            //非拒保核保规则触发
            if (!declinatureRuleModel.getInsuredFlag()) {
                if (isManual) {
                    //人核
                    flag = false;
                    message.append(declinatureRuleModel.getInsuredMessage());
                    logger.info("人核渠道【触发非拒保核保规则<------>进入人核】");
                } else {
                    //拒保
                    logger.info("非人核渠道【触发非拒保核保规则<------>直接拒保】");
                    return createRefuseAcceptResponseDataModel(acceptRequestDataModel.getHeader(), false, declinatureRuleModel.getInsuredMessage());
                }
            } else {
                //投保人健康告知
                boolean appntInform = checkApntInform(acceptRequestDataModel.getRequest().getProductInfo(), custInfoModel);
                if (appntInform) {
                    message.append(String.format(UnderWriteConstant.UNDERWRITING_HEALTH_NOTICE_MESSAGE, custInfoModel.getAppnt().getAppntName()));
                    if (isManual) {
                        flag = false;
                        logger.info("人核渠道<-->【投保人健康告知为是 进入人工核保】");
                    } else {
                        logger.info("非人核渠道【投保人健康告知为是<------>直接拒保】");
                        return createRefuseAcceptResponseDataModel(acceptRequestDataModel.getHeader(), false, message.toString());
                    }
                }
                if (isManual) {
                    //判断被保人健康告知是否为Y Y返回true
                    boolean insInform = this.checkInsInform(acceptRequestDataModel);
                    //除责是否为2 inform节点可能为空
                    InformModel informModel = acceptRequestDataModel.getRequest().getInform();
                    if (informModel != null && StringUtils.equals(AcceptConstant.INFORM_RESULT,
                            informModel.getResult()) && insInform) {
                        flag = false;
                        message.append(AcceptConstant.UNDERWRITING_MESSAGE);
                        logger.info("人核渠道<-->【智能核保结论人核 进入人工核保】");
                    }
                }
            }
        }
        //人核
        if (!flag) {
            if (message.lastIndexOf(AcceptConstant.VERTICAL_BAR) > -1) {
                message.deleteCharAt(message.length() - 1);
            }
            midResultModel.setMidUWFlag("5");
            midResultModel.setUwReson(message.toString());
            return createSuccessAcceptResponseDataModel(acceptRequestDataModel.getHeader(), responseProductInfoModel,
                    true, message.toString());
        }
        return createSuccessAcceptResponseDataModel(acceptRequestDataModel.getHeader(), responseProductInfoModel,
                false, AcceptConstant.CLOUD_UNDERWRITE_MESSAGE);
    }

    /**
     * 构建受理成功返回对象
     *
     * @param headerModel              请求头
     * @param responseProductInfoModel 产品信息对象
     * @return AcceptResponseDataModel
     */
    private AcceptResponseDataModel createSuccessAcceptResponseDataModel(RequestHeaderModel headerModel,
                                                                         ResponseProductInfoModel responseProductInfoModel,
                                                                         boolean flag, String message) {
        ResultModel resultModel = new ResultModel();
        if (flag) {
            resultModel.setResultCode(AcceptConstant.CLOUD_PERSON_UNDERWRITE_CODE);
            resultModel.setResultMessage(message);
        } else {
            resultModel.setResultCode(AcceptConstant.CLOUD_UNDERWRITE_CODE);
            resultModel.setResultMessage(message);
        }
        AcceptResponseDataModel acceptResponseDataModel = AcceptUtil.getResponseResult(headerModel, resultModel, responseProductInfoModel);
        acceptResponseDataModel.setFlag(true);
        return acceptResponseDataModel;
    }

    /**
     * 构建拒保返回对象
     *
     * @param headerModel 请求头
     * @return AcceptResponseDataModel
     */
    private AcceptResponseDataModel createRefuseAcceptResponseDataModel(RequestHeaderModel headerModel,
                                                                        boolean flag, String message) {
        ResultModel resultModel = new ResultModel();
        resultModel.setResultCode(AcceptConstant.RESULT_FAIL_CODE);
        if (flag) {
            resultModel.setResultMessage(String.format(AcceptConstant.CLOUD_DECLINATURE_MESSAGE, message));
        } else {
            resultModel.setResultMessage(message);
        }
        AcceptResponseDataModel acceptResponseDataModel = AcceptUtil.getResponseResult(headerModel, resultModel,
                null);
        acceptResponseDataModel.setFlag(false);
        return acceptResponseDataModel;
    }

    private AcceptResponseDataModel createRefuseAcceptResponseDataModel(RequestHeaderModel headerModel, String
            message) {
        ResultModel resultModel = new ResultModel();
        resultModel.setResultCode(AcceptConstant.RESULT_FAIL_CODE);
        resultModel.setResultMessage(message);
        AcceptResponseDataModel acceptResponseDataModel = AcceptUtil.getResponseResult(headerModel, resultModel,
                null);
        acceptResponseDataModel.setFlag(false);
        return acceptResponseDataModel;
    }

    /**
     * 获取总保费
     *
     * @param calculationList 保费计算任务集合
     * @return ResponseProductInfoModel 产品信息对象
     */
    private ResponseProductInfoModel getPremiumSum(List<TaskResponseModel> calculationList) {
        ResponseProductInfoModel responseProductInfoModel = new ResponseProductInfoModel();
        BigDecimal bigDecimal = BigDecimal.valueOf(0);
        for (TaskResponseModel taskResponseModel : calculationList) {
            bigDecimal = bigDecimal.add(TrialUtil.bigDecimalRoundHalfUp(taskResponseModel.getBigDecimal().doubleValue()));
        }
        responseProductInfoModel.setPayPrem(String.valueOf(bigDecimal.doubleValue()));

        return responseProductInfoModel;
    }

    /**
     * 获取总保费
     *
     * @param responseListModel 计算任务集合
     * @return ResponseProductInfoModel 产品信息对象
     */
    private ResponseProductInfoModel getPremiumSum(ResponseListModel responseListModel) {
        ResponseProductInfoModel responseProductInfoModel = new ResponseProductInfoModel();
        List<TaskResponseModel> calculationList = responseListModel.getCalculation();
        BigDecimal bigDecimal = BigDecimal.valueOf(0);
        for (TaskResponseModel taskResponseModel : calculationList) {
            bigDecimal = bigDecimal.add(TrialUtil.bigDecimalRoundHalfUp(taskResponseModel.getBigDecimal().doubleValue()));
        }
        if (CollectionUtils.isNotEmpty(responseListModel.getPlusPremList())) {
            for (TaskResponseModel taskResponseModel : responseListModel.getPlusPremList()) {
                bigDecimal = bigDecimal.add(taskResponseModel.getBigDecimal());
            }
        }
        responseProductInfoModel.setPayPrem(String.valueOf(bigDecimal.doubleValue()));

        return responseProductInfoModel;
    }

    /**
     * 判断是否触发非拒保核保规则
     *
     * @param insuredTaskResult 投和保任务结果
     * @return DeclinatureRuleModel
     */
    private DeclinatureRuleModel isDeclinatureRule(List<TaskResponseModel> insuredTaskResult) {
        DeclinatureRuleModel declinatureRuleModel = new DeclinatureRuleModel();
        declinatureRuleModel.setInsuredFlag(true);
        StringBuilder sb = new StringBuilder();
        for (TaskResponseModel taskResponseModel : insuredTaskResult) {
            String resultCode = taskResponseModel.getResultCode();
            if (StringUtils.equals(resultCode, AcceptConstant.RESULT_SUCCESS_CODE)) {
                continue;
            }
            if (sb.length() == 0) {
                sb.append(taskResponseModel.getResultMessage());
            } else {
                sb.append("|").append(taskResponseModel.getResultMessage());
            }
            declinatureRuleModel.setInsuredFlag(false);
        }
        declinatureRuleModel.setInsuredMessage(sb.toString());
        return declinatureRuleModel;
    }


    private DeclinatureRuleModel isNonDeclinatureRule(List<TaskResponseModel> taskResponseModelList) {
        DeclinatureRuleModel declinatureRuleModel = new DeclinatureRuleModel();
        declinatureRuleModel.setInsuredFlag(true);
        StringBuilder sb = new StringBuilder();
        taskResponseModelList.stream().forEach(x -> {
            if (productConfig.getUnderWriteList().contains(x.getResultCode())) {
                if (sb.length() == 0) {
                    sb.append(x.getResultMessage());
                } else {
                    sb.append("|").append(x.getResultMessage());
                }
            }
        });
        if (sb.length() > 0) {
            declinatureRuleModel.setInsuredFlag(false);
            declinatureRuleModel.setInsuredMessage(sb.toString());
        }
        return declinatureRuleModel;
    }


    /**
     * 校验受理报文被保人是否存在健康告知
     *
     * @param acceptRequestDataModel 受理请求报文
     * @return true-存在 false-不存在
     */
    private boolean checkInsInform(AcceptRequestDataModel acceptRequestDataModel) {
        List<InsurantModel> insurantModels = acceptRequestDataModel.getRequest().getCustInfo().getInsurants().getInsurant();
        for (InsurantModel insurantModel : insurantModels) {
            if (StringUtils.equals(AcceptConstant.STRING_Y, insurantModel.getInsInform())) {
                return true;
            }
        }
        return false;
    }

    /**
     * 判断是否支持人核
     *
     * @param productModels 产品list
     * @param agencyCode    代理机构
     * @return boolean
     */
    private boolean manualUnderwriting(List<ProductModel> productModels, String agencyCode) {
        boolean flag = false;
        Object obj = redisService.get(AcceptConstant.AGENT_KEY);
        // 判断对象是否为空，
        List<?> agentComs;
        if (obj == null || (agentComs = (List<?>) obj).size() == 0) {
            if (StringUtils.isNotBlank(insuranceAcceptService.getAgentCom(agencyCode))) {
                flag = true;
            }
        } else {
            for (Object agentCom : agentComs) {
                if (StringUtils.equals(agencyCode, String.valueOf(agentCom))) {
                    flag = true;
                    break;
                }
            }
        }
        if (flag) {
            //从缓存查询渠道是否存在非核保产品
            String key = AcceptConstant.NON_MANUAL_UNDERWRITING_PREFIX + agencyCode;
            Object object = redisService.get(key);
            List<?> list;
            if (object != null && (list = (List<?>) object).size() > 0) {
                for (ProductModel productModel : productModels) {
                    String riskCode = productModel.getProdCode();
                    for (Object o : list) {
                        if (StringUtils.equals(riskCode, o.toString())) {
                            return false;
                        }
                    }
                }
            } else {
                return true;
            }
        }
        return flag;
    }

    /**
     * 判断保盾云结论
     *
     * @param conclusion 保盾云分数
     * @param manual     是否支持人核
     * @param request    请求报文
     * @return 1-拒保 2-通过 3-人核
     */
    private int cloudConclusion(ConclusionModel conclusion, boolean manual, RequestModel request) {
        String idNo = conclusion.getId();
        double info = conclusion.getCloud().getInfo();
        List<ProductModel> products = request.getProductInfo().getProducts().getProduct();
        List<InsurantModel> insurants = request.getCustInfo().getInsurants().getInsurant();
        AppntModel appnt = request.getCustInfo().getAppnt();
        //获取conclusion对应的被保人 如果是投保人的结论，变量是null
        InsurantModel insurant = getInsurant(idNo, insurants);
        int result = 2;
        //产品有特殊核保标准
        String standard;
        for (ProductModel product : products) {
            //属于需要调用保盾云的险种
            if (redisService.isCloud(request.getPolicyInfo().getAgencyCode(), product.getProdCode()) &&
                    redisService.isMember(AcceptConstant.REDIS_PREFIX_B003, product.getProdCode())) {
                standard = this.getStandard(product.getProdCode());
                boolean isExemption = redisService.exemptionProduct(product.getProdCode()) ||
                        redisService.isExemptDuty(product.getProdCode(), appnt,
                                insurant, request.getPolicyInfo().getPolApplyDate());
                //结论属于投保人
                if (insurant == null) {
                    if (isExemption) {
                        return judgeCloud(info, standard, manual);
                    }
                } else {
                    //结论属于被保人
                    if (insurant.getInsSeq() == product.getProdInsSeq() && !isExemption) {
                        int temp = judgeCloud(info, standard, manual);
                        if (temp == 1) {
                            return temp;
                        } else if (temp > result) {
                            result = temp;
                        }
                    }
                }
            }
        }
        return result;
    }

    private int judgeCloud(double info, String standard, boolean manual) {
        if (StringUtils.isNotBlank(standard)) {
            List<Double> infos = Arrays.stream(standard.split("\\|")).map(Double::valueOf).collect(Collectors.toList());
            if (manual) {
                //支持人核
                if (infos.size() > 1) {
                    //存在人核标准和拒保标准
                    if (info > infos.get(1)) {
                        //存在拒保直接结束
                        return 1;
                    } else if (info > infos.get(0)) {
                        return 3;
                    }
                } else {
                    if (info > infos.get(0)) {
                        return 3;
                    }
                }
            } else {
                if (info > infos.get(0)) {
                    return 1;
                }
            }
        } else {
            //无指定标准使用默认[0,400](400,500][500,
            if (info > 500) {
                return 1;
            } else {
                if (manual) {
                    if (info > 400) {
                        return 3;
                    }
                } else {
                    if (info > 400) {
                        return 1;
                    }
                }
            }
        }
        return 2;
    }

    private String getStandard(String riskCode) {
        Object standard = redisService.get(AcceptConstant.REDIS_PREFIX_B004 + riskCode);
        return standard == null ? "" : standard.toString();
    }

    private InsurantModel getInsurant(String idNo, List<InsurantModel> insurants) {
        for (InsurantModel insurant : insurants) {
            if (StringUtils.equals(insurant.getIdNo(), idNo)) {
                return insurant;
            }
        }
        return null;
    }
}

